home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / deskbar-applet / handlers / beagle-live.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-04-29  |  12.6 KB  |  382 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import os
  5. import sys
  6. import cgi
  7. import re
  8. import gobject
  9. import gtk
  10. import gnome
  11. import gnome.ui as gnome
  12. import gnomevfs
  13. import deskbar
  14. import deskbar.Handler as deskbar
  15. import deskbar.Utils as deskbar
  16. import deskbar.Match as deskbar
  17. from gettext import gettext as _
  18. from os.path import exists, dirname
  19. from deskbar.defs import VERSION
  20. from deskbar.Utils import is_program_in_path, spawn_async, url_show, url_show_file
  21. MAX_RESULTS = 20
  22.  
  23. try:
  24.     import beagle
  25. except:
  26.     pass
  27.  
  28.  
  29. def _show_start_beagle_dialog(dialog):
  30.     dialog = gtk.Dialog(_('Start Beagle Daemon?'), dialog, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
  31.     dialog.set_default_size(350, 150)
  32.     dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)
  33.     dialog.add_button(_('Start Beagle Daemon'), gtk.RESPONSE_ACCEPT)
  34.     label = gtk.Label(_('The Beagle daemon does not appear to be running.\n You need to start it to use the Beagle Live handler.'))
  35.     dialog.vbox.add(label)
  36.     label.show()
  37.     response = dialog.run()
  38.     dialog.destroy()
  39.     if response == gtk.RESPONSE_ACCEPT:
  40.         print 'Starting Beagle Daemon.'
  41.         if not spawn_async([
  42.             'beagled']):
  43.             print >>sys.stfderr, "Failed to start beagled. Perhaps the beagle daemon isn't installed?"
  44.             warn = gtk.MessageDialog(flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_WARNING, buttons = gtk.BUTTONS_CLOSE, message_format = _('Failed to start Beagle'))
  45.             warn.format_secondary_text(_("Perhaps the beagle daemon isn't installed?"))
  46.             warn.run()
  47.             warn.destroy()
  48.         
  49.     
  50.  
  51.  
  52. def _check_requirements():
  53.     
  54.     try:
  55.         import deskbar
  56.         import beagle
  57.     except Exception:
  58.         e = None
  59.         return (deskbar.Handler.HANDLER_IS_NOT_APPLICABLE, 'Could not load beagle, libbeagle has been compiled without python bindings:' + str(e), None)
  60.  
  61.     if not beagle.beagle_util_daemon_is_running():
  62.         if is_program_in_path('beagled'):
  63.             return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, 'Beagle daemon is not running.', _show_start_beagle_dialog)
  64.         else:
  65.             return (deskbar.Handler.HANDLER_IS_NOT_APPLICABLE, 'Beagled could not be found in your $PATH. Unable to start the beagled daemon', None)
  66.     else:
  67.         return (deskbar.Handler.HANDLER_IS_HAPPY, None, None)
  68.  
  69. HANDLERS = {
  70.     'BeagleLiveHandler': {
  71.         'name': _('Beagle Live'),
  72.         'description': _('Search all of your documents (using Beagle), as you type'),
  73.         'requirements': _check_requirements,
  74.         'version': VERSION } }
  75. TYPES = {
  76.     'Contact': {
  77.         'name': ('fixme:FileAs',),
  78.         'action': 'evolution %(uri)s',
  79.         'icon': 'stock_contact',
  80.         'description': _('Edit contact %s') % '<b>%(name)s</b>',
  81.         'category': 'people' },
  82.     'MailMessage': {
  83.         'name': ('dc:title', 'parent:dc:title'),
  84.         'action': 'evolution %(uri)s',
  85.         'icon': 'stock_mail',
  86.         'extra': {
  87.             'sender': ('fixme:from_name', 'parent:fixme:from_name') },
  88.         'description': _('From %s') % '<i>%(sender)s</i>' + '\n<b>%(name)s</b>',
  89.         'category': 'emails' },
  90.     'File': {
  91.         'name': ('beagle:ExactFilename',),
  92.         'action': (lambda d: url_show_file('file://' + d['uri'])),
  93.         'icon': 'stock_new',
  94.         'description': _('Open %s') % '<b>%(name)s</b>',
  95.         'snippet': True,
  96.         'category': 'files' },
  97.     'FeedItem': {
  98.         'name': ('dc:title',),
  99.         'action': (lambda d: url_show(d['identifier'])),
  100.         'icon': 'stock_news',
  101.         'description': _('News from %s') % '<i>%(publisher)s</i>' + '\n<b>%(name)s</b>',
  102.         'snippet': True,
  103.         'category': 'news',
  104.         'extra': {
  105.             'publisher': ('dc:publisher',),
  106.             'identifier': ('dc:identifier',) } },
  107.     'Note': {
  108.         'name': ('dc:title',),
  109.         'action': 'tomboy --open-note %(uri)s',
  110.         'icon': 'stock_notes',
  111.         'description': _('Note: %s') % '<b>%(name)s</b>',
  112.         'snippet': True,
  113.         'category': 'notes' },
  114.     'IMLog': {
  115.         'name': ('fixme:speakingto',),
  116.         'extra': {
  117.             'client': ('fixme:client',) },
  118.         'action': "beagle-imlogviewer --client %(client)s --highlight-search '%(text)s' %(uri)s",
  119.         'icon': 'im',
  120.         'description': _('With %s') % '<b>%(name)s</b>',
  121.         'snippet': True,
  122.         'category': 'conversations' },
  123.     'Calendar': {
  124.         'name': ('fixme:summary',),
  125.         'action': 'evolution %(uri)s',
  126.         'icon': 'stock_calendar',
  127.         'description': _('Calendar: %s') % '<b>%(name)s</b>',
  128.         'category': 'documents' },
  129.     'WebHistory': {
  130.         'name': ('dc:title',),
  131.         'action': (lambda d: url_show_file(d['uri'])),
  132.         'icon': 'stock_bookmark',
  133.         'description': _('Open History Item %s') % '<i>%(name)s</i>' + '\n%(escaped_uri)s',
  134.         'category': 'web' } }
  135. for key, val in TYPES.items():
  136.     if 'snippet' in val and val['snippet']:
  137.         val['description'] += '%(snippet)s'
  138.         continue
  139.  
  140.  
  141. class BeagleLiveMatch(deskbar.Match.Match):
  142.     
  143.     def __init__(self, handler, result = None, **args):
  144.         '''
  145. \t\tresult: a dict containing:
  146. \t\t\t"name" : a name sensible to display for this match
  147. \t\t\t"uri": the uri of the match as provided by the beagled \'Uri: \'-field
  148. \t\t\t"type": One of the types listed in the TYPES dict
  149.  
  150. \t\t-- and optionally extra fields as provided by the corresponding entry in TYPES.
  151. \t\tFx. "MailMessage". has an extra "sender" entry.
  152. \t\t'''
  153.         deskbar.Match.Match.__init__(self, handler, name = result['name'], **args)
  154.         self.result = result
  155.         action = TYPES[self.result['type']]['action']
  156.         if not callable(action) and action.startswith('beagle-imlogviewer'):
  157.             self.result['uri'] = gnomevfs.get_local_path_from_uri(self.result['uri'])
  158.         
  159.         self._icon = None
  160.         if result['type'] == 'File':
  161.             
  162.             try:
  163.                 self._icon = deskbar.Utils.load_icon_for_file(result['uri'])
  164.             except Exception:
  165.                 pass
  166.             except:
  167.                 None<EXCEPTION MATCH>Exception
  168.             
  169.  
  170.         None<EXCEPTION MATCH>Exception
  171.         if self._icon == None:
  172.             self._icon = handler.ICONS[result['type']]
  173.         
  174.  
  175.     
  176.     def get_category(self):
  177.         
  178.         try:
  179.             return TYPES[self.result['type']]['category']
  180.         except:
  181.             return 'default'
  182.  
  183.  
  184.     
  185.     def get_name(self, text = None):
  186.         if text:
  187.             self.result['text'] = text
  188.             self.result['text'] = self.result['text'].replace("'", "\\'")
  189.         
  190.         return self.result
  191.  
  192.     
  193.     def get_verb(self):
  194.         return TYPES[self.result['type']]['description']
  195.  
  196.     
  197.     def action(self, text = None):
  198.         self.get_name(text)
  199.         action = TYPES[self.result['type']]['action']
  200.         if callable(action):
  201.             action(self.result)
  202.         else:
  203.             action = action % self.result
  204.             args = action.split(' ')
  205.             print 'BeagleLive spawning:', action, args
  206.             spawn_async(args)
  207.  
  208.     
  209.     def get_hash(self, text = None):
  210.         if 'uri' in self.result:
  211.             return self.result['uri']
  212.         
  213.  
  214.  
  215.  
  216. class SnippetContainer:
  217.     
  218.     def __init__(self, hit):
  219.         self.hit = hit
  220.         self.snippet = None
  221.  
  222.  
  223.  
  224. class BeagleLiveHandler(deskbar.Handler.SignallingHandler):
  225.     
  226.     def __init__(self):
  227.         deskbar.Handler.SignallingHandler.__init__(self, ('system-search', 'best'))
  228.         self.counter = { }
  229.         self.snippets = { }
  230.         self.set_delay(500)
  231.  
  232.     
  233.     def initialize(self):
  234.         self.beagle = beagle.Client()
  235.         self.ICONS = self._BeagleLiveHandler__load_icons()
  236.  
  237.     
  238.     def __load_icons(self):
  239.         res = { }
  240.         for t in TYPES.iterkeys():
  241.             icon_file = TYPES[t]['icon']
  242.             if not icon_file:
  243.                 continue
  244.             
  245.             res[t] = deskbar.Utils.load_icon(icon_file)
  246.         
  247.         return res
  248.  
  249.     
  250.     def query(self, qstring):
  251.         beagle_query = beagle.Query()
  252.         beagle_query.add_text(qstring)
  253.         beagle_query.connect('hits-added', self.hits_added, qstring, MAX_RESULTS)
  254.         
  255.         try:
  256.             self.beagle.send_request_async(beagle_query)
  257.         except:
  258.             return None
  259.  
  260.         self.counter[qstring] = { }
  261.  
  262.     
  263.     def _on_snippet_received(self, request, response, query, container, qstring, qmax):
  264.         container.snippet = response.get_snippet()
  265.         self._on_hit_added(query, container, qstring, qmax)
  266.  
  267.     
  268.     def _on_snippet_closed(self, request, query, container, qstring, qmax):
  269.         if container.snippet == None:
  270.             self._on_hit_added(query, container, qstring, qmax)
  271.         
  272.         container.hit.unref()
  273.  
  274.     
  275.     def _on_hit_added(self, query, hit, qstring, qmax):
  276.         fire_signal = False
  277.         snippet = None
  278.         if hit.__class__ == SnippetContainer:
  279.             hit = hit.hit
  280.             snippet = hit.snippet
  281.             fire_signal = True
  282.         
  283.         if hit.get_type() not in self.counter[qstring]:
  284.             self.counter[qstring][hit.get_type()] = 0
  285.         
  286.         if self.counter[qstring][hit.get_type()] >= qmax:
  287.             return None
  288.         
  289.         hit_type = TYPES[hit.get_type()]
  290.         result = {
  291.             'uri': hit.get_uri(),
  292.             'type': hit.get_type() }
  293.         name = None
  294.         for prop in hit_type['name']:
  295.             
  296.             try:
  297.                 name = hit.get_properties(prop)[0]
  298.             except:
  299.                 
  300.                 try:
  301.                     name = hit.get_property(prop)
  302.  
  303.  
  304.             if name != None:
  305.                 result['name'] = name
  306.                 break
  307.                 continue
  308.         
  309.         if name == None:
  310.             result['name'] = _('?')
  311.         
  312.         if 'extra' in hit_type:
  313.             for prop, keys in hit_type['extra'].items():
  314.                 val = None
  315.                 for key in keys:
  316.                     
  317.                     try:
  318.                         val = hit.get_properties(key)[0]
  319.                     except:
  320.                         
  321.                         try:
  322.                             val = hit.get_property(key)
  323.  
  324.  
  325.                     if val != None:
  326.                         result[prop] = val
  327.                         break
  328.                         continue
  329.                 
  330.                 if val == None:
  331.                     result[prop] = _('?')
  332.                     continue
  333.             
  334.         
  335.         for key, val in result.items():
  336.             if key == 'uri' or key == 'identifier':
  337.                 result['escaped_' + key] = cgi.escape(val)
  338.                 continue
  339.             result[key] = cgi.escape(val)
  340.         
  341.         if snippet != None:
  342.             tmp = re.sub('<.*?>', '', snippet)
  343.             tmp = re.sub('</.*?>', '', tmp)
  344.             result['snippet'] = "\n<span foreground='grey' size='small'>%s</span>" % cgi.escape(tmp)
  345.         else:
  346.             result['snippet'] = ''
  347.         self.counter[qstring][hit.get_type()] = self.counter[qstring][hit.get_type()] + 1
  348.         match = BeagleLiveMatch(self, result)
  349.         if fire_signal:
  350.             self.emit_query_ready(qstring, [
  351.                 match])
  352.         else:
  353.             return match
  354.  
  355.     
  356.     def hits_added(self, query, response, qstring, qmax):
  357.         hit_matches = []
  358.         for hit in response.get_hits():
  359.             if hit.get_type() not in TYPES:
  360.                 print 'WARNING: Beagle live seen an unknown type:', hit.get_type()
  361.                 continue
  362.             
  363.             if 'snippet' in TYPES[hit.get_type()] and TYPES[hit.get_type()]['snippet']:
  364.                 req = beagle.SnippetRequest()
  365.                 req.set_query(query)
  366.                 req.set_hit(hit)
  367.                 container = SnippetContainer(hit)
  368.                 hit.ref()
  369.                 req.connect('response', self._on_snippet_received, query, container, qstring, qmax)
  370.                 req.connect('closed', self._on_snippet_closed, query, container, qstring, qmax)
  371.                 self.beagle.send_request_async(req)
  372.                 continue
  373.             
  374.             match = self._on_hit_added(query, hit, qstring, qmax)
  375.             if match != None:
  376.                 hit_matches.append(match)
  377.                 continue
  378.         
  379.         self.emit_query_ready(qstring, hit_matches)
  380.  
  381.  
  382.